package haxeframe.animation;

import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.ui.Multitouch;
import haxe.Timer;
import haxeframe.animation.AnimatedSprite;
import haxeframe.physics.Symbol;

import haxeframe.physics.Assets;
import haxeframe.utils.Utils;
import flash.Lib;

import openfl.display.Tilesheet;

class Juggler
{
	public static var sprites:Array<AnimatedSprite> = new Array<AnimatedSprite>();

	public static var paused:Bool = false;

	private static var _then:Int;
	private static var _now:Int;
	private static var _elapsed:Int;

	private static var timer:Timer;

	public static var maxFrameRate:Int = 30;

	private static var _canvases:Map<Graphics, Map<Tilesheet, Array<Dynamic>>> = new Map<Graphics, Map<Tilesheet, Array<Dynamic>>>();

	private static var dispatcher:Sprite;

	public static var lowPerformance:Bool = false;

	public static function addCanvas(graphics:Graphics):Void
	{
		if(_canvases.get(graphics) == null)
			_canvases.set(graphics, new Map<Tilesheet, Array<Dynamic>>());
	}

	public static function add(sprite:AnimatedSprite):Void
	{
		if(timer == null) timer = Timer.delay(update,Math.ceil(1000/maxFrameRate));
		// if(dispatcher == null){
		// 	dispatcher = new Sprite();
		// 	Lib.current.stage.addChild(dispatcher);
		// 	dispatcher.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		// }
		if(!Utils.valueInArray(sprite, sprites)){
			sprites.push(sprite);
			if(Assets.getTilesheet(sprite.sourceBitmapData) == null){
				Assets.addTilesheet(sprite.sourceBitmapData, sprite.tilesheetXml);
			}
			sprite.tilesheet = Assets.getTilesheet(sprite.sourceBitmapData);
		}
	}

	private static function onEnterFrame(event:Event):Void
	{
		update();
	}

	public static function addSymbolToCanvas(symbol:Symbol, canvas:Graphics):Void
	{
	// TODO
	}

	private static function update():Void
	{
       	_now = Lib.getTimer();
       	_elapsed = _now - _then;
        _then = _now;
        
    	if(!paused){

	       	for(thisSprite in sprites){
		       	if(_now - thisSprite.lastUpdate >= 1000/thisSprite.fps){
		       		thisSprite.update((_now-thisSprite.lastUpdate)*.001);
		       		thisSprite.lastUpdate = _now;
		       		if(lowPerformance) remove(thisSprite);
		    	}
		    }

	    }
        timer = Timer.delay(update,Math.ceil(1000/maxFrameRate));
	}

	public static function clear():Void
	{
		sprites = [];
	}

	public static function remove(sprite:AnimatedSprite):Void
	{
		for(s in 0...sprites.length){
			if(sprites[s] == sprite){
				sprites.splice(s,1);
				break;
			}
		}
		// sprites.remove(sprite);
	}
}